import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;


public class TestServer {

	static int port = 5060;
	
	private final static int noCall = 0;
	private final int ready = 1;
	private final static int established = 2;
	

	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		//ServerSocket Server = null;

		
		//Socket clientSocket = null;
		
		InetAddress addr = InetAddress.getLocalHost();

	    // Get IP Address
	    String ipAddr = addr.toString();

	    // Get hostname
	    String hostname = addr.getHostName();

		//System.out.println("hostname:" + hostname + " IP: " + ipAddr);
		
		
		/*Server = new ServerSocket(port);
		
		
		while(true) {
			clientSocket = Server.accept();
			in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			out = new PrintStream(clientSocket.getOutputStream());
			
			while(true) {
				
				line = in.readLine();
				System.out.println(line);
				
				
			}
			
			
		}*/
		
	    //System.out.println((int)(Math.random()*100000000*100));
	    
		///UDP
		
		byte[] buf = new byte[1000];
	    DatagramPacket packet = new DatagramPacket(buf, buf.length);
	    DatagramSocket socket;

	    ServerProfile serverprofile = new ServerProfile();
	    DatagramSocket RTPSocket = new DatagramSocket(serverprofile.getRTPPort());
	    
	    
	    socket = new DatagramSocket(port);
	    
	    
	    File file = new File("Record.txt");
	    file.createNewFile();
	    FileWriter txt = new FileWriter(file);
	    PrintWriter out = new PrintWriter(txt);
	    

	    
	    
	    //boolean flag = true;
	    
	    
	    /*///////////////////////////////////
	    ////////////////////////////////
	    
	    FileInputStream fis = new FileInputStream(file);

	      // Here BufferedInputStream is added for fast reading.
	     
	     DataInputStream dis = new DataInputStream(fis);

	     BufferedReader br = new BufferedReader(new InputStreamReader(dis));
	     
	     String t;
	     String temp = "";
	      // dis.available() returns 0 if the file does not have more lines.
	      while ((t = br.readLine()) != null) {
	    	  temp+= t+"\n";
	    	  
	      }

	    /*  System.out.print(temp);
	    
	    	InetAddress ip = InetAddress.getByName("192.168.1.2");
	    
	    DatagramPacket st  = new DatagramPacket(temp.getBytes(), temp.getBytes().length, ip, 52715);
	    ////////////////////////////////
	    /////////////////////////////*/
	    
	    //for(int i = 0; i < 10; i++)
	    //socket.send(st);
	    
	    
	    
	    String rcvd="";
	    
	    //for (int i = 0; i < 10; i++) {
	    System.out.println("Ready........");
	    socket.receive(packet);
	    rcvd = new String(packet.getData(), 0, packet.getLength()); 
	        //System.out.println(packet.getSocketAddress());
	    //System.out.println(rcvd);
	        
	        
	        
	        
	        
	        //String array = rcvd.replaceAll("\\\\+", "/");

	        
	        //for(int j = 0; j < array.length; j++)
	        //System.out.println(array);
	        
	        
	        
	        
	        
	        
	        
	        
	        
	    out.write(rcvd);
	    
	    
	    
	    /*count sdp length
	    String tempcut [];
	    tempcut = rcvd.split("Content-Length: ");
	    System.out.println(tempcut[1]);
	    System.out.println(tempcut[1].length());
	    */
	        
	        
	        
	        //out.close();
	        
	        //break;
	    //}
	    
		BufferedReader in;
		MessageEngine engine;
	    ServerStatus status;
	    MemberProfile profile;
	    MemberList memberlist;
	    
	    
	    engine =  new MessageEngine();
	    
	    status = new ServerStatus(noCall);
	    in = new BufferedReader(new StringReader(rcvd)); 
	    profile = new MemberProfile(packet.getAddress(), packet.getPort());
	    memberlist = new MemberList();
	    
	    socket.connect(packet.getAddress(), packet.getPort());
	    
	    //System.out.println(rcvd + "\n");
	    
	    String line;
	    
	    boolean flag = true;
	    boolean SDPflag = false;
	    
	    while((line = in.readLine()) != null && flag){
	    	if(line.matches("^BYE.*"))
	    	{
	    		if(status.getStatus() == established){
	    			
	    		}
	    	} else if(line.matches("^INVITE.*")){	    		
	    		if(status.getStatus() == noCall){
	    			if(!memberlist.checkMember(packet.getAddress())){
	    				status.updatestatus();
	    				while((line = in.readLine()) != null){// && !line.matches("^a=")){
	    					profile = engine.InviteHandler(profile, line);
	    					if(line.matches("^Content"))
	    						SDPflag = true;
	    					if(SDPflag == true) {
	    						profile = engine.SDPHandler(profile, line);
	    					}
	    				}
	    				SDPflag = false;
	    				flag = false;
	    			}
	    		}
	    	} else if(line.matches("^ACK.*")){
	    		
	    	}
	    }
	    
	    
	    
	    
	    
	    
	    //System.out.println(engine.ResponseHandler(profile, serverprofile));
	    DatagramPacket tryingpacket = new DatagramPacket(engine.Trying(profile, serverprofile).getBytes(), 
	    			engine.Trying(profile, serverprofile).getBytes().length);
	    DatagramPacket ringingpacket = new DatagramPacket(engine.Ringing(profile, serverprofile).getBytes(), 
    			engine.Ringing(profile, serverprofile).getBytes().length);
	    DatagramPacket sendpacket = new DatagramPacket(engine.ResponseHandler(profile, serverprofile).getBytes(), 
	    			engine.ResponseHandler(profile, serverprofile).getBytes().length );
	    
	    //System.out.println("Send: \n" + engine.ResponseHandler(profile, serverprofile));
	    
	    
	    socket.send(tryingpacket);
	    System.out.println(engine.Trying(profile, serverprofile));
	    try {
			Thread.currentThread();
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    /*socket.send(ringingpacket);
	    out.write(engine.Ringing(profile, serverprofile));
	    System.out.println(engine.Ringing(profile, serverprofile));
	    
	    
	    try {
			Thread.currentThread();
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
	    
	    RTPSocket.connect(profile.getInetAdress(), profile.getRTPPort());
	    
	    socket.send(sendpacket);
	    //out.write(engine.ResponseHandler(profile, serverprofile));
	    //System.out.println(engine.ResponseHandler(profile, serverprofile));
	    
	    
	    socket.receive(packet);
        rcvd = new String(packet.getData(), 0, packet.getLength()); 
        //System.out.println(packet.getSocketAddress());
        //System.out.println(rcvd);
	    
        //out.write(rcvd);
	    out.close();
	    System.out.println(rcvd);
	    
	    while(true){
	    	RTPSocket.receive(packet);
	    	System.out.println("OK");
	    }
	    
	    
	    
	    
	    
	    /*/System.out.println(rcvd + "\n");
	   // System.out.println("Send: \n" + engine.ResponseHandler(profile, serverprofile));
	    RTPSocket.connect(profile.getInetAdress(), profile.getRTPPort());
	    /*for(;;) {
	    	socket.send(tryingpacket);
	    	socket.send(ringingpacket);
	    socket.send(sendpacket);
	    }*/
	    //socket.receive(packet);
	    //rcvd = new String(packet.getData(), 0, packet.getLength());
	    //if(rcvd.contains("ACK"))
	    	//System.out.println(rcvd);
	    //System.out.println(rcvd + "\n");
	    
	    
	    
	    
	    
	    //System.out.println("My profile: \n" + profile.getName() + "\t" + profile.getCall_ID() + "\n" + profile.getVia() + "\t" + 
	    		//profile.getCSeq() + "\t" + profile.getFrom() + "\t" + profile.getTo() + "\t" + profile.getMaxFowards());
	    
	    //System.out.println("RTPPort: " + profile.getRTPPort());
	    
	    //System.out.println("Send: \n" + engine.ResponseHandler(profile, serverprofile));
	        
	    
	   
	    
		
	}

}
